
#include "StateManager.h"

IStateManager* StateManager::_stateManager;

StateManager::StateManager() :
	curState(NULL),
	preState(NULL),
	_stateList(NULL)
{
}

StateManager::~StateManager()
{
	//Delete all the states in the statList array
}

void StateManager::Update()
{
}

void StateManager::ChangeState(int nextState, int currentState, bool fromPause)
{
	//Find the next state on the list and call its enter 
	//with this state as the prevState argument
	if(!fromPause)
	{
		curState = _stateList->at(nextState);
		preState = _stateList->at(currentState);
		_stateList->at(nextState)->Enter(currentState);
	}
	else
	{
		curState = _stateList->at(nextState);
		preState = _stateList->at(PAUSE);
		_stateList->at(nextState)->Unpause();
	}
}	

void StateManager::Cleanup()
{
	int i = 0;
	//Call cleanup on every state in the stateList
	for(std::vector<State*>::iterator it = _stateList->begin();
		it != _stateList->end(); it++)
	{
		(*it)->Cleanup();
		delete _stateList->at(i);
		i++;
	}

	//Clear the state list
	_stateList->clear();
}

State* StateManager::CurrentState()
{
	return curState;
}

State* StateManager::PreviousState()
{
	return preState;
}

void StateManager::Initialize()
{
	//Create a vector of state objects
	_stateList = new std::vector<State*>();

	//Push a new state object on to the list untill
	//all levels/states are loaded
														//_stateList array index
	_stateList->push_back(new SeekState());				//0
	_stateList->push_back(new PursuitState());			//1
	_stateList->push_back(new ArriveState());			//2
	_stateList->push_back(new InterposeState());		//3
	_stateList->push_back(new OffsetPursuitState());	//4
	_stateList->push_back(new FleeState());				//5
	_stateList->push_back(new EvadeState());			//6
	_stateList->push_back(new HideState());				//7
	_stateList->push_back(new WallAvoidState());		//8
	_stateList->push_back(new PathFollowingState());	//9
	_stateList->push_back(new WanderState());			//10 aka F1
	_stateList->push_back(new SeperationState());		//11 aka F2
	_stateList->push_back(new AlignmentState());		//12 aka F3
	_stateList->push_back(new CohesionState());			//13 aka F4
	_stateList->push_back(new FlockingState());			//14 aka F5
	_stateList->push_back(new PauseState());			//15 aka P
	_stateList->push_back(new SeekEvadeState());		//16 aka F6

	//Aquire resource files 
	setupResources();

	//Initialize window and camera
	createViewports();

	// initialize all game states in stateList
	for(std::vector<State*>::iterator my_iterator = _stateList->begin();
		my_iterator != _stateList->end(); my_iterator++)
	{
		(*my_iterator)->Initialize();
	}

	curState = _stateList->at(0);
}

void StateManager::UpdateStarted(const Ogre::FrameEvent &gameTime)
{
	//Call update on every state
	for(std::vector<State*>::iterator my_iterator = _stateList->begin();
		my_iterator != _stateList->end(); my_iterator++)
	{
		(*my_iterator)->UpdateStarted(gameTime);
	}
}

void StateManager::UpdateEnded(const Ogre::FrameEvent &gameTime)
{
	//Call update end on every state
	for(std::vector<State*>::iterator my_iterator = _stateList->begin();
		my_iterator != _stateList->end(); my_iterator++)
	{
		(*my_iterator)->UpdateEnded(gameTime);
	}

}

//Moved from State class so individual states do not set up resources 
void StateManager::setupResources(void)
{
   // Load resource paths from config file
   Ogre::ConfigFile cf;
   cf.load(GameServices::OgreManager()->GetResourcesConfig());

   // Go through all sections & settings in the file
   Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();


   Ogre::String secName, typeName, archName;
   while (seci.hasMoreElements())
   {
       secName = seci.peekNextKey();
       Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
       Ogre::ConfigFile::SettingsMultiMap::iterator i;
       for (i = settings->begin(); i != settings->end(); ++i)
       {
           typeName = i->first;
           archName = i->second;
           Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
               archName, typeName, secName);
       }
   }
}

//Moved from State class so individual states do not set up viewports 
void StateManager::createViewports(void)
{
	GameServices::OgreManager()->GetRenderWindow()->getViewport(0)->setBackgroundColour(Ogre::ColourValue(0,0,0));

   // Alter the camera aspect ratio to match the viewport
   GameServices::OgreManager()->GetCamera()->setAspectRatio(
       Ogre::Real(GameServices::OgreManager()->GetRenderWindow()->getViewport(0)->getActualWidth()) / Ogre::Real(GameServices::OgreManager()->GetRenderWindow()->getViewport(0)->getActualHeight()));

   //Position the root node at 0,0,0 so child placement is simple
   GameServices::OgreManager()->GetSceneManager()->getRootSceneNode()->setPosition(0,0,0);

}


